package com.ljj.examisto.ui.activity

import android.annotation.SuppressLint
import android.app.AlarmManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager.PERMISSION_GRANTED
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import com.ljj.examisto.R
import com.ljj.examisto.data.service.TimeService
import com.ljj.examisto.databinding.ActivityHomeBinding
import com.ljj.examisto.ui.dialog.MenuDialog
import com.ljj.examisto.ui.fragment.NoExamsFragment
import com.ljj.examisto.ui.fragment.ShowerFragment
import com.ljj.examisto.util.DatabaseHelper
import com.ljj.examisto.util.Logger.TAG
import com.ljj.examisto.util.ToastManager

class HomeActivity : AppCompatActivity() {
    companion object {
        fun backHome(context: Context) {
            val intent = Intent(context, HomeActivity::class.java)
            intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
            context.startActivity(intent)
        }
    }

    private lateinit var binding: ActivityHomeBinding
    private lateinit var dbHelper: DatabaseHelper
    private lateinit var quitCallback: OnBackPressedCallback
    private var isReceiverRegistered = false
    private var lastBackPressTime = 0L
    private val backPressThreshold by lazy { resources.getInteger(R.integer.back_press_threshold) }
    private val examChangeReceiver by lazy {
        object : BroadcastReceiver() {
            override fun onReceive(context: Context?, intent: Intent?) {
                if (intent?.action == "com.ljj.examisto.ACTION_EXAM_CHANGE") {
                    safeUpdateShower()
                }
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        checkPermission()
        initProperty()
        init()
        setupViews()
    }

    override fun onStart() {
        super.onStart()
        safeUpdateShower()
    }

    override fun onDestroy() {
        super.onDestroy()
        unregisterReceiver()
    }

    /* 流程函数 */
    private fun checkPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            if (checkSelfPermission(android.Manifest.permission.POST_NOTIFICATIONS) !=
                PERMISSION_GRANTED
            ) {
                requestPermissions(
                    arrayOf(android.Manifest.permission.POST_NOTIFICATIONS),
                    1
                )
            }
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            val alarmManager = getSystemService(ALARM_SERVICE) as AlarmManager
            if (!alarmManager.canScheduleExactAlarms()) {
                AlertDialog.Builder(this)
                    .setTitle("精准闹钟权限授权请求")
                    .setMessage("请授权 ${getString(R.string.app_name)} 的精准闹钟权限")
                    .setPositiveButton("前往设置") { _, _ ->
                        val intent = Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM)
                        startActivity(intent)
                    }
                    .setNegativeButton("取消") { _, _ ->
                        ToastManager.interruptedToast(
                            this,
                            "已取消授权精准闹钟权限",
                            Toast.LENGTH_SHORT
                        )
                    }
                    .show()
            }
        }
    }

    private fun initProperty() {
        binding = ActivityHomeBinding.inflate(layoutInflater)
        dbHelper = DatabaseHelper.getInstance(this)
    }

    private fun init() {
        TimeService.startService(this)
        registerReceiver()
    }

    private fun setupViews() {
        setContentView(binding.root)
        setupQuitCallBack()
        setupMenuButton()
        setupAddExamButton()
    }

    /* 工具函数 */
    private fun setupQuitCallBack() {
        quitCallback = object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                val currentTime = System.currentTimeMillis()
                if (currentTime - lastBackPressTime < backPressThreshold) {
                    finish()
                } else {
                    lastBackPressTime = currentTime
                    ToastManager.interruptedToast(
                        this@HomeActivity,
                        "再次点击返回键退出应用",
                        Toast.LENGTH_SHORT
                    )
                }
            }
        }
        // 注册回调
        onBackPressedDispatcher.addCallback(this, quitCallback)
    }

    @SuppressLint("UnspecifiedRegisterReceiverFlag")
    private fun registerReceiver() {
        if (!isReceiverRegistered) {
            val filter = IntentFilter("com.ljj.examisto.ACTION_EXAM_CHANGE")
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                registerReceiver(
                    examChangeReceiver,
                    filter,
                    RECEIVER_NOT_EXPORTED
                )
            } else {
                registerReceiver(examChangeReceiver, filter)
            }
            isReceiverRegistered = true
        }
    }

    private fun unregisterReceiver() {
        if (isReceiverRegistered) {
            try {
                unregisterReceiver(examChangeReceiver)
                isReceiverRegistered = false
            } catch (e: IllegalArgumentException) {
                Log.d(TAG, "${e.message}")
            }
        }
    }

    @SuppressLint("ClickableViewAccessibility")
    private fun setupMenuButton() {
        binding.btnMenu.setOnTouchListener { view, event ->
            when (event.action) {
                MotionEvent.ACTION_DOWN -> {
                    binding.btnMenu.setBackgroundResource(R.drawable.ic_menu_pressed)
                    true
                }
                MotionEvent.ACTION_MOVE -> {
                    if (!isTouchInsideView(view, event)) {
                        binding.btnMenu.setBackgroundResource(R.drawable.ic_menu)
                    }
                    true
                }
                MotionEvent.ACTION_UP -> {
                    binding.btnMenu.setBackgroundResource(R.drawable.ic_menu)
                    if (isTouchInsideView(view, event)) {
                        MenuDialog(this).show()
                    }
                    true
                }
                MotionEvent.ACTION_CANCEL -> {
                    binding.btnMenu.setBackgroundResource(R.drawable.ic_menu)
                    true
                }
                else -> false
            }
        }
    }

    @SuppressLint("ClickableViewAccessibility")
    private fun setupAddExamButton() {
        binding.btnAddExam.setOnTouchListener { view, event ->
            when (event.action) {
                MotionEvent.ACTION_DOWN -> {
                    binding.btnAddExam.setBackgroundResource(R.drawable.ic_add_pressed)
                    true
                }
                MotionEvent.ACTION_MOVE -> {
                    if (!isTouchInsideView(view, event)) {
                        binding.btnAddExam.setBackgroundResource(R.drawable.ic_add)
                    }
                    true
                }
                MotionEvent.ACTION_UP -> {
                    binding.btnAddExam.setBackgroundResource(R.drawable.ic_add)
                    if (isTouchInsideView(view, event)) {
                        val intent = Intent(this, AddExamActivity::class.java)
                        startActivity(intent)
                    }
                    true
                }
                MotionEvent.ACTION_CANCEL -> {
                    binding.btnAddExam.setBackgroundResource(R.drawable.ic_add)
                    true
                }
                else -> false
            }
        }
    }

    private fun safeUpdateShower() {
        if (isDestroyed || isFinishing) return
        runOnUiThread {
            if (!supportFragmentManager.isStateSaved) {
                val fragmentTransaction = supportFragmentManager.beginTransaction()
                if (dbHelper.hasExams()) {
                    fragmentTransaction.replace(R.id.frag_shower, ShowerFragment())
                } else {
                    fragmentTransaction.replace(R.id.frag_shower, NoExamsFragment()
                    )
                }
                fragmentTransaction.commitAllowingStateLoss()
            }
        }
    }

    private fun isTouchInsideView(view: View, event: MotionEvent): Boolean {
        val x = event.x
        val y = event.y
        return x >= 0 && x <= view.width && y >= 0 && y <= view.height
    }
}